import type { PageType } from '../../../../../lib/page_handler/type'
import type { IPaginationLoadType } from '../index'
import { PageHandler } from '../../../../../lib/page_handler'
import { BaiduPageType } from '../../../../../lib/page_handler/platform/baidu/types'
import { BIAN_PAGINATION_CONFIG, BianPageType } from '../../../../../lib/page_handler/platform/bian/types'
import { GREASY_FORK_PAGINATION_CONFIG, GreasyForkPageType } from '../../../../../lib/page_handler/platform/greasyfork/types'
import { PollingHandler } from '../../../../../lib/polling_handler'
import { ToolKit } from '../../../../../lib/utils/toolkit'
import { HOSTNAME, logger, SUPPORTED_PLATFORMS } from '../../../../../types/constants'
import { SYMBOLS } from '../../../../../types/interfaces'

export abstract class AutoPaginationBase {
  abstract loadType: IPaginationLoadType
  abstract checkPage(): boolean

  // @Decorators.Core
  readonly pageType: PageType = PageHandler.getCurrentPageType()

  /**
   * 获取分页组件链接选择器
   */
  getPageItemLinkSelector(): string {
    switch (HOSTNAME) {
      case SUPPORTED_PLATFORMS.BAI_DU: {
        switch (this.pageType) {
          case BaiduPageType.Web:
            return '#page a:has([class^="page-item"])'
          case BaiduPageType.News:
            return '#page .page-inner a'
          default:
            return ''
        }
      }
      case SUPPORTED_PLATFORMS.GREASY_FORK:
        switch (this.pageType) {
          case GreasyForkPageType.SCRIPT_LIST:
          case GreasyForkPageType.SCRIPT_VERSIONS:
          case GreasyForkPageType.SCRIPT_FEEDBACK:
            return GREASY_FORK_PAGINATION_CONFIG.selector.link
          default:
            return ''
        }
      case SUPPORTED_PLATFORMS.BIAN:
        switch (this.pageType) {
          case BianPageType.List:
            return BIAN_PAGINATION_CONFIG.selector.link
          default:
            return ''
        }
      default:
        return ''
    }
  }

  /**
   * 计算最大页码数
   */
  clacMaxPageNum(selector: string): number {
    const items = $(selector)

    if (!items.length) {
      logger.info(`${SYMBOLS.STATUS.WARNING} 分页元素为空，无法获取最大页码数，默认返回1`, selector)
      return 1
    }

    return ToolKit.ui.element.extractMaxNumberFromElements(items)
  }

  /**
   * 通过轮询计算最大页码数
   */
  clacMaxPageNumWithPolling(selector: string): Promise<number> {
    return new Promise((resolve, _reject) => {
      const handler = () => {
        const items = $(selector)
        const maxPage = ToolKit.ui.element.extractMaxNumberFromElements(items)
        resolve(maxPage)
      }

      PollingHandler.getInstance().api.awaitElement(selector, handler, {
        onTimeout: () => resolve(1), // 超时时返回默认值1
      })
    })
  }
}
